package com.tianji.learning.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.ObjectUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.dto.ReplyDTO;
import com.tianji.learning.domain.enums.QuestionStatus;
import com.tianji.learning.domain.po.InteractionQuestion;
import com.tianji.learning.domain.po.InteractionReply;
import com.tianji.learning.domain.query.ReplyPageQuery;
import com.tianji.learning.domain.vo.ReplyVO;
import com.tianji.learning.mapper.InteractionQuestionMapper;
import com.tianji.learning.mapper.InteractionReplyMapper;
import com.tianji.learning.service.IInteractionReplyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 互动问题的回答或评论 服务实现类
 * </p>
 *
 * @author 东哥
 * @since 2024-11-12
 */
@Service
@RequiredArgsConstructor
public class InteractionReplyServiceImpl extends ServiceImpl<InteractionReplyMapper, InteractionReply> implements IInteractionReplyService {

    private final InteractionReplyMapper replyMapper;
    private final InteractionQuestionMapper questionMapper;
    private final UserClient userClient;


    /**
     * 新增【回答】或者【评论】 (用户端和管理端公用)
     *
     * @param replyDTO
     */
    @Override
    public void saveReply(ReplyDTO replyDTO) {
        // 1.属性拷贝
        InteractionReply reply = BeanUtils.copyBean(replyDTO, InteractionReply.class);

        // 2.填充数据
        reply.setUserId(UserContext.getUser());

        // 3.保存
        this.save(reply);

        // 4.累加评论数或者累加回答数
        // 4.1.判断当前回复的类型是否是回答
        boolean isAnswer = replyDTO.getAnswerId() == null;
        if (!isAnswer) {
            // 4.2.是评论，则需要更新上级回答的评论数量
            lambdaUpdate()
                    .setSql("reply_times = reply_times + 1")
                    .eq(InteractionReply::getId, replyDTO.getAnswerId())
                    .update();
        }


    }

    /**
     * 分页查询【回答】或【评论】列表
     *
     * @param query
     * @return
     */
    @Override
    public PageDTO<ReplyVO> pageReply(ReplyPageQuery query) {
        // 1.问题ID和回答ID不能同时为空
        Long questionId = query.getQuestionId();
        Long answerId = query.getAnswerId();
        if (ObjectUtils.isEmpty(questionId) && ObjectUtils.isEmpty(answerId)){
            throw new BadRequestException("问题ID和回答ID不能同时为空");
        }

        // 2.分页查询
        Page<InteractionReply> pageResult = this.lambdaQuery()
                .eq(ObjectUtils.isNotEmpty(questionId), InteractionReply::getQuestionId, questionId)
                .eq(ObjectUtils.isNotEmpty(answerId), InteractionReply::getAnswerId, answerId)
                .eq(InteractionReply::getHidden, false)
                .page(query.toMpPageDefaultSortByCreateTimeDesc());
        List<InteractionReply> records = pageResult.getRecords();
        if (ObjectUtils.isEmpty(records)){
            return PageDTO.empty(pageResult);
        }

        // 3.根据ID查询回答者和最近一次回答信息
        Set<Long> userIds = new HashSet<>();
        Set<Long> answerIds = new HashSet<>();
        // 3.1得到问题当中的提问者ID和最近一次回答ID
        for (InteractionReply record : records) {
            if (!record.getAnonymity()){
                userIds.add(record.getUserId());
            }
            answerIds.add(record.getAnswerId());
        }
        // 3.2根据ID查询回答
        Map<Long, InteractionReply> replyMap = new HashMap<>(answerIds.size());
        if (ObjectUtils.isNotEmpty(answerIds)){
            List<InteractionReply> replyList = replyMapper.selectBatchIds(answerIds);
            for (InteractionReply reply : replyList) {
                replyMap.put(reply.getId(), reply);
                if (!reply.getAnonymity()){
                    userIds.add(reply.getUserId());
                }
            }
        }
        // 3.3根据ID查询用户信息
        Map<Long, UserDTO> userMap = new HashMap<>(userIds.size());
        if (ObjectUtils.isNotEmpty(userIds)){
            List<UserDTO> userList = userClient.queryUserByIds(userIds);
            userMap = userList.stream().collect(Collectors.toMap(UserDTO::getId, Function.identity()));
        }

        // 4.封装VO
        List<ReplyVO> voList = new ArrayList<>(records.size());
        for (InteractionReply record : records) {
            // 4.1属性拷贝
            ReplyVO vo = BeanUtils.copyBean(record, ReplyVO.class);
            voList.add(vo);
            if (!record.getAnonymity()){
                UserDTO userDTO = userMap.get(record.getUserId());
                if (ObjectUtils.isNotEmpty(userDTO)){
                    vo.setUserId(userDTO.getId());
                    vo.setUserName(userDTO.getName());
                    vo.setUserIcon(userDTO.getIcon());
                }
            }
            // 4.2封装回答信息
            InteractionReply reply = replyMap.get(record.getTargetReplyId());
            if (ObjectUtils.isNotEmpty(reply)){
                vo.setContent(reply.getContent());
                vo.setCreateTime(reply.getCreateTime());
                //点赞数
                vo.setLikedTimes(reply.getLikedTimes());
                UserDTO targetUser = userMap.get(reply.getUserId());
                vo.setTargetUserName(targetUser.getName());
            }
        }

        return PageDTO.of(pageResult,voList);
    }
}
